using Microsoft.AspNetCore.Identity;
using oms.Shared.utils;

namespace oms.Shared.Authentication;

/// <summary>
/// 适配 ASP.NET Core Identity 的密码加密器
/// 该加密器使用 <see cref="PasswordUtil"/> 进行密码加密。
/// </summary>
/// <typeparam name="TUser"></typeparam>
public class IdentityPasswordHasher<TUser> : IPasswordHasher<TUser>
    where TUser : class
{
    /// <summary>
    /// 对用户密码进行加密（自动生成盐值）
    /// </summary>
    /// <param name="user">用户实体（未使用，可空）</param>
    /// <param name="password">密码明文</param>
    /// <returns>加密串（格式：16位盐值 + 加密结果）</returns>
    /// <exception cref="InvalidOperationException">密码加密失败时抛出</exception>
    public string HashPassword(TUser user, string password)
    {
        try
        {
            // 调用自定义 PasswordUtil 加密，返回带盐值的加密串
            return PasswordUtil.Encode(password);
        }
        catch (Exception ex)
        {
            // 捕获加密异常，转为框架认可的格式
            throw new InvalidOperationException("密码加密失败", ex);
        }
    }

    /// <summary>
    /// 验证用户提供的密码是否与存储的哈希值匹配
    /// </summary>
    /// <param name="user">用户实体（未使用，可空）</param>
    /// <param name="hashedPassword">存储的哈希密码（格式：16位盐值 + 加密结果）</param>
    /// <param name="providedPassword">用户提供的密码明文</param>
    /// <returns>验证结果（成功/失败）</returns>
    /// <exception cref="InvalidOperationException">密码验证异常时抛出</exception>
    public PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword)
    {
        try
        {
            // 调用自定义 PasswordUtil 验证
            var isMatch = PasswordUtil.Matches(providedPassword, hashedPassword);
            return isMatch
                ? PasswordVerificationResult.Success
                : PasswordVerificationResult.Failed;
        }
        catch
        {
            // 加密串格式错误或验证异常，均视为验证失败
            return PasswordVerificationResult.Failed;
        }
    }
}